programming4us
           
 
 
Programming

Programming WCF Services : The Response Service (part 1) - Designing a Response Service Contract

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
3/8/2012 11:25:33 AM
The programming model of queued calls described so far was one-sided: the client posted a one-way message to a queue, and the service processed that message. This model is sufficient when the queued operations are one-way calls by nature. However, the queued service may need to report back to its client on the result of the invocation, or return results or even errors. By default, this is not possible: WCF equates queued calls with one-way calls, which inherently forbids any such response. In addition, queued services (and their clients) are potentially disconnected. If a client posts a queued call to a disconnected service, by the time the service finally gets the message and processes it, there may no longer be a client to return the values to. The solution is to have the service report back to a client-provided queued service.Figure 1shows the architecture of such a solution.


Figure 1. A response service


The response service is just another queued service in the system. The response service may be disconnected toward the client as well, or it may share the client’s process, or it may be hosted in a separate process or even on a separate machine. If the response service shares the client’s process, when the client is launched the response service will start processing the queued responses. Having the response service in a separate process (or even on a separate machine) from the client’s helps to further decouple lifeline-wise the response service from the client or clients that use it.


Note:

Not all queued services require a response service. Be pragmatic, and use a response service only where appropriate; that is, where it adds the most value.


1. Designing a Response Service Contract

As with any WCF service, the client and the service need to agree beforehand on the response contract and what it will be used for; that is, whether it will be used for returned values and error information, or just returned values. Note that you can also split the response service into two services, and have one response service for results and another for faults and errors. As an example, consider the ICalculator contract implemented by the queued MyCalculator service:

[ServiceContract]
interface ICalculator
{
   [OperationContract(IsOneWay = true)]
   void Add(int number1,int number2);
   //More operations
}
class MyCalculator : ICalculator
{...}

The MyCalculator service is required to respond to its client with the result of the calculation and report on any errors. The result of the calculation is an integer, and the error is in the form of the ExceptionDetail data contract . The ICalculatorResponse contract could be defined as:

[ServiceContract]
interface ICalculatorResponse
{
   [OperationContract(IsOneWay = true)]
   void OnAddCompleted(int result,ExceptionDetail error);
   //More operations
}

The response service supporting ICalculatorResponse needs to examine the returned error information; notify the client application, the user, or the application administrator on the method completion; and make the results available to the interested parties. Example 1 shows a simple response service that supports ICalculatorResponse.

Example 1. A simple response service
class MyCalculatorResponse : ICalculatorResponse
{
   public void OnAddCompleted(int result,ExceptionDetail error)
   {
      if(error != null)
      {
         //Handle error
      }
      else
      {
         MessageBox.Show("Result = " + result,"MyCalculatorResponse");
      }
   }

   //More operations
}

As demonstrated by Example 1, the response service is just that—a simple service. There is nothing special about it other than its designation as a response service.

1.1. Response address and method ID

There are two immediate problems with the implementation of both MyCalculator and MyCalculatorResponse. The first is that the same response service could be used to handle the response (or completion) of multiple calls on multiple queued services, and yet, as listed in Example 9-21, MyCalculatorResponse (and more importantly, the clients it serves) has no way of distinguishing between responses. The solution for that is to have the client that issued the original queued call tag the call by associating it with some unique ID, or at least an ID that is unique enough across that client’s application. The queued service MyCalculator needs to pass that ID to the response service MyCalculatorResponse, so that it can apply its custom logic regarding that ID. Note that the service typically has no direct use for the ID; all it needs to do is pass it along.

The second problem is how to enable the queued service to discover the address of the response service. Unlike with duplex callbacks, there is no built-in support in WCF for passing the response service’s reference to the queued service, so the queued service needs to manually construct a proxy to the response service and invoke the operations of the response contract. While the response contract is decided upon at design time, and the binding is always NetMsmqBinding, the queued service lacks the address of the response service to be able to respond. You could place that address in the service host config file (in a client section) but such a course of action is to be avoided. The main reason is that the same queued service could be called by multiple clients, each with its own dedicated response service and address.

One possible solution is to explicitly pass both the client-managed ID and the desired response service address as parameters to every operation on the queued service contract:

[ServiceContract]
interface ICalculator
{
   [OperationContract(IsOneWay = true)]
   void Add(int number1,int number2,string responseAddress,string methodId);
}

					  

Much the same way, the queued service could explicitly pass the method ID to the response service as a parameter to every operation on the queued response contract:

[ServiceContract]
interface ICalculatorResponse
{
   [OperationContract(IsOneWay = true)]
   void OnAddCompleted(int result,ExceptionDetail error,string methodId);
}

1.2. The ResponseContext class

While passing the address and the ID as explicit parameters would work, it does distort the original contract, and it introduces plumbing-level parameters alongside business-level parameters in the same operation. A better solution is to have the client store the response address and operation ID in the outgoing message headers of the call. Using the message headers this way is a general-purpose technique for passing out-of-band information to the service (information that is otherwise not present in the service contract). 

Since the client needs to pass both the address and the method ID in the message headers, a single primitive type parameter will not do. Instead, use my ResponseContext class, defined in Example 2.

Example 2. The ResponseContext class
[DataContract]
public class ResponseContext
{
   [DataMember]
   public readonly string ResponseAddress;

   [DataMember]
   public readonly string FaultAddress;

   [DataMember]
   public readonly string MethodId;

   public ResponseContext(string responseAddress,string methodId) :
                                               this(responseAddress,methodId,null)
   {}
   public ResponseContext(string responseAddress) : this(responseAddress,
                                                        Guid.NewGuid().ToString())
   {}
   public ResponseContext(string responseAddress,string methodId,
                          string faultAddress)
   {
      ResponseAddress = responseAddress;
      MethodId = methodId;
      FaultAddress = faultAddress;
   }

   public static ResponseContext Current
   {
      get
      {
         return GenericContext<ResponseContext>.Current.Value;
      }
      set
      {
         GenericContext<ResponseContext>.Current =
                                        new GenericContext<ResponseContext>(value);
      }
   }
   //More members
}

					  

ResponseContext provides a place to store both the response address and the ID. In addition, if the client wants to use a separate response service for faults, ResponseContext provides a field for the fault response service address. The client is responsible for constructing an instance of ResponseContext with a unique ID. While the client can supply that ID as a construction parameter, the client can also use the constructor of ResponseContext, which takes just the response address, and have that constructor generate a GUID for the ID. To streamline the act of storing a ResponseContext instance in and retrieving it from the headers, ResponseContext provides the Current property, which merely encapsulates my GenericContext<T>. The client can provide an ID for each method call (even when dealing with a sessionful queued service) by using a different instance of ResponseContext for each call.

Other -----------------
- Programming WCF Services : Queued Versus Connected Calls - Requiring Queuing
- Programming WCF Services : Queued Services - Playback Failures
- DotNetNuke Skinning : Package and Deploy
- Unit Testing in Visual Studio 2010 (part 2) - Running a battery of tests
- Unit Testing in Visual Studio 2010 (part 1) - Creating unit tests
- Microsoft ASP.NET 3.5 : AJAX-Enabled Web Services - Remote Calls via Page Methods
- Microsoft ASP.NET 3.5 : WCF Services for ASP.NET AJAX Applications
- Mobile Game Networking Essentials : Network Programming and J2ME
- Mobile Game Networking Essentials : Multiplayer Game Basics & Network Game Problems and Solutions
- Software Testing with Visual Studio Team System 2008 : Debug and running web test (part 2) - Running the test
- Software Testing with Visual Studio Team System 2008 : Debug and running web test (part 1) - Settings for .testrunconfig file
- Visual Studio Team System 2008 : Web test editor (part 3) - Toolbar properties
- Visual Studio Team System 2008 : Web test editor (part 2) - Other request properties
- Visual Studio Team System 2008 : Web test editor (part 1) - Web test properties & Web test request properties
- Build Mobile Websites and Apps for Smart Devices : Design for Mobile - Standing on the Shoulders of Giants
- Build Mobile Websites and Apps for Smart Devices : Design for Mobile - Build a Better Mouse
- Developing BlackBerry Tablet Applications with Flex 4.5 : Create a Flex Mobile Project (part 4) - Reading and setting author information for debug
- Developing BlackBerry Tablet Applications with Flex 4.5 : Create a Flex Mobile Project (part 3) - Setup Device
- Developing BlackBerry Tablet Applications with Flex 4.5 : Create a Flex Mobile Project (part 2) - Setup Simulator
- Developing BlackBerry Tablet Applications with Flex 4.5 : Create a Flex Mobile Project (part 1)
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us